<style>
    .rule-express-error {
        border-bottom: #f60854 solid 1px;
    }
</style>
<template>
    <div :class="className">
        <div style="float: left;font-size: 12px">
            <span v-show="showLabel">{{label}}</span>
            {{not?' 非':' '}}
            (
        </div>
        <div style="float: left">
            <div style="float: left">
                <div v-if="leftType=='express'" style="float: left;margin-left: 5px">
                    <express-type location="left" @validateExpress="validateExpress" @calexp="handle"
                                  :onlyArithmetic="true" :ruleAtoms="ruleAtoms" :express="this.express.left.express"
                                  :operations="operations"/>
                </div>
                <Dropdown :transfer="true" class='rule-tree-dropdown' trigger="click" @on-click="leftTypeSelect">
                    <a href="javascript:void(0)" style="color: #fa8c16">
                        {{leftType==''?'左表达式':(leftType=='atom'?leftAtomName:'')}}
                        <Tooltip content="选择左表达式类型" placement="top">
                            <Icon type="ios-arrow-down" size="12"/>
                        </Tooltip>
                    </a>
                    <DropdownMenu slot="list">
                        <Dropdown :transfer="true" placement="right-start" :pageIndexChangeCallBack="leftPageChange"
                                  :page-data="leftAtomPageInfo">
                            <DropdownItem>
                                原子
                                <Icon type="ios-arrow-forward"></Icon>
                            </DropdownItem>
                            <DropdownMenu slot="list">
                                <DropdownItem :key="item.key" v-for="item in leftAtomToSelect" :name="'atom_'+item.key">
                                    {{ item.name }}
                                </DropdownItem>
                            </DropdownMenu>
                        </Dropdown>
                        <DropdownItem name="express">表达式</DropdownItem>
                    </DropdownMenu>
                </Dropdown>
            </div>
            <div style="float: left;margin-left: 5px;">
                <Dropdown :transfer="true" class='rule-tree-dropdown' trigger="click" @on-click="operationSelected">
                    <a href="javascript:void(0)" style="color: #c803ff">
                        {{this.operationName}}
                        <Tooltip content="选择操作符类型" placement="top">
                            <Icon type="ios-arrow-down" size="12"/>
                        </Tooltip>
                    </a>
                    <DropdownMenu slot="list" v-if="operationsSelect.length>0">
                        <DropdownItem :key="item.key" v-for="item in operationsSelect" :name="item.key">{{ item.name
                            }}
                        </DropdownItem>
                    </DropdownMenu>
                </Dropdown>
            </div>
            <div style="float: left">
                <div v-if="rightType=='value'" style="float: left;margin-left: 5px;padding-left: 5px">
                    <CommonType @calexp="handle" :atomKey="leftAtom" :inputType="inputType" :inputConfig="inputConfig"
                                :valueIndex="0" :valueNames="valueNames" :values="values"/>
                </div>
                <div v-if="rightType=='express'" style="float: left;margin-left: 5px">
                    <express-type location="right" @validateExpress="validateExpress" @calexp="handle"
                                  :onlyArithmetic="true" :ruleAtoms="ruleAtoms" :express="this.express.right.express"
                                  :operations="operations"/>
                </div>
                <Dropdown :transfer="true" class='rule-tree-dropdown' trigger="click" @on-click="rightTypeSelect">
                    <a href="javascript:void(0)" style="color: #026ff1">
                        {{rightType==''?'右表达式':(rightType=='atom'?rightAtomName:'')}}
                        <Tooltip content="选择右表达式类型" placement="top">
                            <Icon type="ios-arrow-down" size="12"/>
                        </Tooltip>
                    </a>
                    <DropdownMenu slot="list">
                        <DropdownItem name="value">输入值</DropdownItem>
                        <Dropdown :transfer="true" placement="right-start" :pageIndexChangeCallBack="rightPageChange"
                                  :page-data="rightAtomPageInfo">
                            <DropdownItem>
                                原子
                                <Icon type="ios-arrow-forward"></Icon>
                            </DropdownItem>
                            <DropdownMenu slot="list">
                                <DropdownItem :key="item.key" v-for="item in rightAtomToSelect"
                                              :name="'atom_'+item.key">{{ item.name }}
                                </DropdownItem>
                            </DropdownMenu>
                        </Dropdown>
                        <DropdownItem name="express">表达式</DropdownItem>
                    </DropdownMenu>
                </Dropdown>
            </div>
        </div>
        <div style="float: left;margin-left: 5px;">)</div>
        <div style="clear:both"></div>
    </div>
</template>
<style lang="less" scoped>
</style>
<script>
    import ruiMixin from "../../mixin/rule-mixin";
    import InType from "./InType";
    import CommonType from "../../component/express/CommonType"
    import {
        genTernaryExpression,
        genOperator,
        genRight,
    } from '../../component/util/index'

    export default {
        name: 'express-type',
        mixins: [ruiMixin],
        components: {
            'InType': InType,
            'CommonType': CommonType
        },
        props: {
            express: {
                type: Object
            },
            depth: {
                type: Number,
                require: true
            },
            ruleAtoms: {
                type: Array,
                require: true
            },
            operations: {
                type: Array,
                require: true
            },
            onlyArithmetic: {
                type: Boolean,
                default: () => {
                    return false;
                }
            },
            label: {
                type: String,
                default: () => {
                    return '';
                }
            },
            not: {
                type: Boolean,
                default: () => {
                    return false;
                }
            },
            index: {
                type: Number,
                default: () => {
                    return 1;
                }
            },
            showLabel: {
                type: Boolean,
                default: () => {
                    return false;
                }
            },
            location: {
                type: String,
                default: () => {
                    return ''
                }
            }
        },
        data() {
            return {
                leftAtom: '',
                leftAtomName: '选择原子',
                rightAtom: '',
                leftCheck: true,
                rightAtomName: '选择原子',
                operation: '',
                operationName: '选择操作符',
                inputType: 'text',
                inputConfig: {},
                atomsToSelect: [],
                operationsSelect: [],
                values: [],
                valueNames: [],
                leftType: '',
                operatorType: '',
                operatorCheck: true,
                rightType: '',
                rightCheck: true,
                init: false,
                leftAtomPageInfo: {
                    pageSize: 5,
                    pageIndex: 1,
                    enable: true,
                    total: 100
                },
                rightAtomPageInfo: {
                    pageSize: 5,
                    pageIndex: 1,
                    enable: true,
                    total: 100
                }
            }
        },
        mounted() {
            if (!this.express) {
                return;
            }
            this.leftType = this.express.left.type;
            if (this.leftType == 'atom') {
                this.leftAtom = this.express.left.atom.key;
                this.leftAtomName = this.express.left.atom.name;
            }
            this.rightType = this.express.right.type;
            if (this.rightType == 'atom') {
                this.rightAtom = this.express.right.atom.key;
                this.rightAtomName = this.express.right.atom.name;
            }
            if (this.leftType == 'atom') {
                this.inputType = this.express.left.atom.component;
                this.inputConfig = this.express.left.atom.componentConfig;
            }
            if (this.express.right.valueNames != '') {
                this.valueNames.push(...this.express.right.valueNames.split(','));
            }
            if (this.express.right.value != '' && this.inputType != 'cascader') {
                this.express.right.value.split(',').forEach(str => {
                    this.values.push(parseFloat(str));
                });
            }
            this.operation = this.express.operator.key;
            this.operatorType = this.express.operator.value;
            this.operationName = this.express.operator.name == '' ? '选择操作符' : this.express.operator.name;
            this.$nextTick(() => {
                this.init = true;
            })
            this.atomsToSelect.push(...this.ruleAtoms)
            this.leftAtomPageInfo.total = this.atomsToSelect.length;
            this.rightAtomPageInfo.total = this.atomsToSelect.length;

        },
        computed: {
            className() {
                this.checkExpressValidate();
                if (this.onlyArithmetic) {
                    return 'expressWidthCal';
                }
                // return (this.rightCheck && this.leftCheck && this.operatorCheck) ? '' : 'rule-express-error';
                return (this.rightCheck&&this.leftCheck&&this.operatorCheck)?'expressWidthCal':'expressWidthCal rule-express-error';
            },
            rightAtomToSelect() {
                if (this.atomsToSelect.length > this.rightAtomPageInfo.pageSize) {
                    let indexStart = (this.rightAtomPageInfo.pageIndex - 1) * this.rightAtomPageInfo.pageSize;
                    let indexEnd = (this.rightAtomPageInfo.pageIndex) * this.rightAtomPageInfo.pageSize;
                    return this.atomsToSelect.slice(indexStart == 0 ? 0 : (indexStart - 1), indexEnd)
                } else {
                    return this.atomsToSelect;
                }
            },
            leftAtomToSelect() {
                if (this.atomsToSelect.length > this.leftAtomPageInfo.pageSize) {
                    let indexStart = (this.leftAtomPageInfo.pageIndex - 1) * this.leftAtomPageInfo.pageSize;
                    let indexEnd = (this.leftAtomPageInfo.pageIndex) * this.leftAtomPageInfo.pageSize;
                    return this.atomsToSelect.slice(indexStart == 0 ? 0 : (indexStart - 1), indexEnd)
                } else {
                    return this.atomsToSelect;
                }
            }
        },
        methods: {
            handle() {
                this.$emit('calexp');
            },
            leftPageChange(pageIndex) {
                this.leftAtomPageInfo.pageIndex = pageIndex;
            },
            rightPageChange(pageIndex) {
                this.rightAtomPageInfo.pageIndex = pageIndex;
            },
            validateExpress(location, validate) {
                if (location == 'left') {
                    this.leftCheck = validate;
                }
                if (location == 'right') {
                    this.rightCheck = validate;
                }
                this.$emit('validate', this.rightCheck && this.leftCheck && this.operatorCheck);
            },
            checkExpressValidate() {
                if (this.operation == '') {
                    this.operatorCheck = false;
                } else {
                    this.operatorCheck = true;
                }
                if (this.leftType == '' || (this.leftType == 'atom' && this.leftAtom == '')|| (this.leftType == 'value' && this.values.join('') == '')) {
                    this.leftCheck = false;
                } else if (this.leftType != 'express') {
                    this.leftCheck = true;
                }
                if (this.rightType == '' || (this.rightType == 'atom' && this.rightAtom == '') || (this.rightType == 'value' && this.values.join('') == '')) {
                    this.rightCheck = false;
                } else if (this.rightType != 'express') {
                    this.rightCheck = true;
                }
                this.$emit('validate', this.rightCheck && this.leftCheck && this.operatorCheck);
                this.$emit('validateExpress', this.location, this.rightCheck && this.leftCheck && this.operatorCheck);
            },
            leftTypeSelect(name) {
                if ((name === 'express' && this.leftType == 'express')) {
                    return;
                }
                if (name === 'express') {
                    this.leftType = 'express';
                    this.leftAtom = '';
                    this.inputType = 'text';
                    this.inputConfig = {};
                    this.express.left.type = "express";
                    delete this.express.left.atom;
                    this.express.left.express = genTernaryExpression();
                    if (this.express.right.type == 'value') {
                        this.express.right.type = '';
                        this.express.right.value = '';
                        this.values = [];
                        this.valueNames = [];
                        this.express.right.valueNames = '';
                        this.rightType = '';
                        this.operation = '';
                        this.operationName = '选择操作符';
                        this.express.operator.key = '';
                        this.express.operator.name = '';
                        this.express.operator.value = '';
                        this.express.operator.type = '';
                    }
                } else if (name.indexOf("atom_") > -1) {
                    this.leftType = 'atom';
                    this.leftAtomSelected(name.replace("atom_", ''));
                    delete this.express.left.express;
                } else if (name === 'value') {
                    this.leftType = name;
                    delete this.express.left.atom;
                    this.express.left.type = "value";
                    this.express.left.value = "";
                    delete this.express.left.express;
                } else {
                    this.leftType = '';
                    this.express.left.type = "";
                    delete this.express.left.atom;
                    delete this.express.left.express;
                }
                this.handle()
            },
            leftAtomSelected(name) {
                let selectAtom, self = this;
                this.ruleAtoms.forEach(atom => {
                    if (atom.key == name) {
                        selectAtom = self.clone(atom)
                    }
                })
                if (!this.onlyArithmetic) {
                    if (selectAtom.operatorScope === 'all') {
                        this.operationsSelect = this.clone(this.operations)
                    } else if (selectAtom.operatorScope === 'cust' && selectAtom.operatorTypes.length) {
                        this.operationsSelect = [];
                        this.operations.forEach(operation => {
                            selectAtom.operatorTypes.forEach(type => {
                                if (type === operation.key) {
                                    self.operationsSelect.push(operation)
                                }
                            })
                        })
                    }
                } else {
                    self.operationsSelect = this.clone(this.arithmeticOperator);
                }
                this.leftAtom = name;
                this.leftAtomName = selectAtom.name;
                this.operationName = '选择操作符';
                this.operation = '';
                this.operatorType = 'fromAtom';
                this.inputType = selectAtom.component;
                this.inputConfig = selectAtom.componentConfig
                this.express.left.type = "atom";
                this.express.left.atom = selectAtom;
                this.express.operator = genOperator()
                this.express.operator.type = 'fromAtom'
                this.express.right = genRight()
                this.rightType = '';
                this.rightAtom = '';
                this.rightAtomName = '';
                this.handle()
            },
            operationSelected(name) {
                if (name == this.operation) {
                    return;
                }
                this.operationsSelect.forEach(item => {
                    if (name == item.key) {
                        this.operation = item.key;
                        this.operationName = item.name;
                        this.express.operator.key = item.key;
                        this.express.operator.name = item.name;
                        this.express.operator.value = item.value;
                    }
                })
                this.handle()
                this.values.splice(0, this.values.length === 1 ? 1 : (this.values.length - 1));
                this.valueNames.splice(0, this.valueNames.length === 1 ? 1 : (this.valueNames.length - 1));
            },
            rightTypeSelect(name) {
                if ((name === 'express' && this.rightType == 'express')) {
                    return;
                }
                if (name === 'express') {
                    this.rightType = name;
                    this.express.right.type = "express";
                    delete this.express.right.atom;
                    this.express.right.value = "";
                    this.express.right.express = genTernaryExpression();
                } else if (name.indexOf("atom_") > -1) {
                    this.rightType = 'atom';
                    delete this.express.right.express;
                    this.express.right.value = "";
                    this.rightAtomSelect(name.replace("atom_", ''));
                    delete this.express.right.express;
                } else if (name === 'value') {
                    this.rightType = name;
                    delete this.express.right.atom;
                    this.express.right.type = "value";
                    this.express.right.value = "";
                    delete this.express.right.express;
                } else {
                    this.rightType = '';
                    delete this.express.right.atom;
                    this.express.right.type = "";
                    this.express.right.value = "";
                    delete this.express.right.express;
                }
                this.handle()
            },
            rightAtomSelect(name) {
                let selectAtom, self = this;
                this.ruleAtoms.forEach(atom => {
                    if (atom.key == name) {
                        selectAtom = self.clone(atom)
                    }
                })
                this.rightAtom = name;
                this.rightAtomName = selectAtom.name;
                this.express.right.type = "atom";
                this.express.right.atom = selectAtom;
                this.handle()
            },
            typeChange() {
                if (!this.init) {
                    return;
                }
                if (this.onlyArithmetic) {
                    this.operationsSelect = this.clone(this.arithmeticOperator);
                    return;
                }
                //左右类型都为空则不处理
                if (this.leftType == '' && this.rightType == '') {
                    return;
                }

                if (this.operatorType == 'compare' && this.express.operator.type == 'compare') {
                    return;
                } else {
                    this.operationsSelect = this.clone(this.arithmeticOperator);
                    if (this.express.operator.type != 'compare') {
                        this.operatorType = 'compare';
                        this.operationName = '选择操作符';
                        this.express.operator = genOperator()
                        this.express.operator.type = 'compare'
                        this.operation = '';
                    }
                }

                this.handle()
            }
        },
        watch: {
            values() {
                if (this.express.right.type == 'value') {
                    this.express.right.valueNames = this.valueNames.join(',')
                    this.express.right.value = this.values.join(',');
                }
                this.handle()
            },
            leftType() {
                this.typeChange();
            },
            rightType() {
                this.typeChange();
            },
        }
    }
</script>
